#include "mainwindow.h"

MainWindow::MainWindow(const std::string& df):dbfile(df),doc(dbfile)
{
    if (dbfile.empty() || !Glib::file_test(dbfile,Glib::FILE_TEST_EXISTS))
    {
        dbfile=Glib::get_home_dir()+"/.local/share/sdms/sdms.db";
        doc.set_dbfile(dbfile);
    }
    set_title("Personal Reading Library");
    set_border_width(0);
    set_default_size(800,600);
    set_icon_from_file(utils::get_data_dir()+"images/logo.png");

    //copy or link zotero database
    //if (!Glib::file_test(dbfile,Glib::FILE_TEST_EXISTS))

    //add custom iconset
    add_iconset();

    //menubar
    Glib::RefPtr<Gtk::ActionGroup> m_actiongroup = Gtk::ActionGroup::create();

    m_actiongroup->add( Gtk::Action::create("MenuFile", "_File") );
    m_actiongroup->add( Gtk::Action::create("SyncZotero", "Sync from zotero","Sync from zotero sqlite3 database"),
                        sigc::mem_fun(*this, &MainWindow::on_action_file_synczotero) );
    m_actiongroup->add( Gtk::Action::create("ImportData", "Import Data","Import reading,writing data from a sqlite backup file"),
                        sigc::mem_fun(*this, &MainWindow::on_action_file_import) );
    m_actiongroup->add( Gtk::Action::create("ExportData", "Export Data","Export reading,writing data to a sqlite backup file"),
                        sigc::mem_fun(*this, &MainWindow::on_action_file_export) );
    m_actiongroup->add( Gtk::Action::create("Quit", Gtk::Stock::QUIT),
                        sigc::mem_fun(*this, &MainWindow::on_action_file_quit) );

    m_actiongroup->add( Gtk::Action::create("MenuView", "_View") );
    m_fullscreenAction=Gtk::ToggleAction::create("FullScreen", Gtk::Stock::FULLSCREEN);
    m_actiongroup->add( m_fullscreenAction,
                        sigc::mem_fun(*this, &MainWindow::on_action_view_fullscreen) );
    m_actiongroup->add( Gtk::Action::create("Books",Gtk::StockID("PRL-BOOK"), "Books","View all books in the library"),
                        sigc::mem_fun(*this, &MainWindow::on_action_view_book) );
    m_actiongroup->add( Gtk::Action::create("Articles", Gtk::StockID("PRL-ARTICLE"),"Articles","View all articles in the library"),
                        sigc::mem_fun(*this, &MainWindow::on_action_view_article) );
    m_actiongroup->add( Gtk::Action::create("NoAttachment",Gtk::StockID("NOATTACHMENT"), "No Attachment","View all items which has no attachment"),
                        sigc::mem_fun(*this, &MainWindow::on_action_view_noattachment) );
    m_actiongroup->add( Gtk::Action::create("AllItems", Gtk::StockID("PRL-ALLITEMS"),"All items","View all items"),
                        sigc::mem_fun(*this, &MainWindow::on_action_view_allitems) );

    m_actiongroup->add( Gtk::Action::create("MenuFilter", "Fi_lter") );
    m_actiongroup->add( Gtk::Action::create("NotReading",Gtk::StockID("NOTREADING"), "Not Reading","Dispaly the items that has not been reading"),
                        sigc::mem_fun(*this, &MainWindow::on_action_filter_notreading) );

    m_actiongroup->add( Gtk::Action::create("NoTag",Gtk::StockID("NOTAG"),"No Tag","Display the items that has no tag"),
                        sigc::mem_fun(*this, &MainWindow::on_action_filter_notag) );
    m_actiongroup->add( Gtk::Action::create("NoPublisher", Gtk::StockID("NOPUBLISHER"),"No Publisher","Display the items that has no publisher information"),
                        sigc::mem_fun(*this, &MainWindow::on_action_filter_nopublisher) );

    m_actiongroup->add( Gtk::Action::create("MenuHelp", "_Help") );
    m_actiongroup->add( Gtk::Action::create("About", Gtk::Stock::ABOUT,"About","About this program"),
                        sigc::mem_fun(*this, &MainWindow::on_action_help_about) );

    Glib::RefPtr<Gtk::UIManager> m_refUIManager = Gtk::UIManager::create();
    m_refUIManager->insert_action_group(m_actiongroup);
    add_accel_group(m_refUIManager->get_accel_group());

    Glib::ustring ui_info =
        "<ui>"
        "  <menubar name='MenuBar'>"
        "    <menu action='MenuFile'>"
        "      <menuitem action='SyncZotero'/>"
        "      <separator/>"
        "      <menuitem action='ImportData'/>"
        "      <menuitem action='ExportData'/>"
        "      <separator/>"
        "      <menuitem action='Quit'/>"
        "    </menu>"
        "    <menu action='MenuView'>"
        "      <menuitem action='FullScreen'/>"
        "      <separator/>"
        "      <menuitem action='Books'/>"
        "      <menuitem action='Articles'/>"
        "      <separator/>"
        "      <menuitem action='NoAttachment'/>"
        "      <menuitem action='AllItems'/>"
        "    </menu>"
        "    <menu action='MenuFilter'>"
        "      <menuitem action='NotReading'/>"
        "      <separator/>"
        "      <menuitem action='NoTag'/>"
        "      <menuitem action='NoPublisher'/>"
        "    </menu>"
        "    <menu action='MenuHelp'>"
        "      <menuitem action='About'/>"
        "    </menu>"
        "  </menubar>"
        "  <toolbar  name='ToolBar'>"
        "    <toolitem action='NotReading'/>"
        "    <toolitem action='NoTag'/>"
        "    <toolitem action='NoPublisher'/>"
        "      <separator/>"
        "    <toolitem action='NoAttachment'/>"
        "    <toolitem action='Books'/>"
        "    <toolitem action='Articles'/>"
        "    <toolitem action='AllItems'/>"
        "      <separator/>"
        "    <toolitem action='Quit'/>"
        "  </toolbar>"
        "</ui>";

    m_refUIManager->add_ui_from_string(ui_info);
    m_refUIManager->signal_connect_proxy().connect(sigc::mem_fun(this, &MainWindow::install_menu_hints));

    Gtk::VBox* vbox1=Gtk::manage(new Gtk::VBox());
    Gtk::VBox* vbox2=Gtk::manage(new Gtk::VBox());
    Gtk::VBox* vbox3=Gtk::manage(new Gtk::VBox());
    //Gtk::HBox* hbox1=Gtk::manage(new Gtk::HBox());
    //Gtk::HBox* hbox2=Gtk::manage(new Gtk::HBox());

    Gtk::Widget* menubar = m_refUIManager->get_widget("/MenuBar");
    Gtk::Widget* toolbar = m_refUIManager->get_widget("/ToolBar");
    vbox1->pack_start(*menubar, Gtk::PACK_SHRINK);
    vbox1->pack_start(*toolbar, Gtk::PACK_SHRINK);

    Gtk::Notebook* notebook=Gtk::manage(new Gtk::Notebook());
    Gtk::ScrolledWindow* sw1=Gtk::manage(new Gtk::ScrolledWindow());
    Gtk::ScrolledWindow* sw2=Gtk::manage(new Gtk::ScrolledWindow());
    Gtk::ScrolledWindow* sw3=Gtk::manage(new Gtk::ScrolledWindow());
    Gtk::ScrolledWindow* sw4=Gtk::manage(new Gtk::ScrolledWindow());
    sw1->add(publisherview);
    sw2->add(tagview);
    sw3->add(writingview);
    sw4->add(docview);
    sw1->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
    sw2->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
    sw3->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
    sw4->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
    notebook->set_tab_pos(Gtk::POS_BOTTOM);
    //notebook->set_scrollable();
    notebook->append_page(*sw1,"Publisher");
    notebook->append_page(*sw2,"Tag");
    notebook->append_page(*sw3,"Writing");
    notebook->append_page(readingview,"Reading");

    vbox2->pack_start(*notebook);

    Gtk::HPaned* hpan1=Gtk::manage(new Gtk::HPaned());
    hpan1->add1(*vbox2);
    vbox3->pack_start(filterview,Gtk::PACK_SHRINK);
    vbox3->pack_start(*sw4);
    hpan1->add2(*vbox3);
    vbox1->pack_start(*hpan1);
    Gtk::Label* label1=Gtk::manage(new Gtk::Label("Personal Reading Library, Version 0.1"));
    statusbar.pack_end(*label1,Gtk::PACK_SHRINK);
    vbox1->pack_end(statusbar,Gtk::PACK_SHRINK);
    add(*vbox1);

    publisherview.set_documents(&doc);
    publisherview.set_docview(&docview);
    publisherview.set_filterview(&filterview);
    publisherview.update();
    Gtk::Requisition req=publisherview.size_request();
    //此处窗口高度过大时，会导致GUI崩溃
    //设置为默认主窗口高度
    //notebook->set_size_request(get_width()/3,get_height());

    writingview.set_documents(&doc);
    writingview.set_docview(&docview);
    writingview.set_filterview(&filterview);

    tagview.set_documents(&doc);
    tagview.set_docview(&docview);
    tagview.set_filterview(&filterview);

    docview.set_documents(&doc);
    docview.set_tagview(&tagview);
    docview.set_writingview(&writingview);
    docview.set_readingview(&readingview);
    docview.set_publisherview(&publisherview);
    docview.set_statusbar(&statusbar);

    filterview.set_documents(&doc);
    filterview.set_docview(&docview);

    readingview.set_documents(&doc);
    readingview.set_filterview(&filterview);


    //publisherview.update();
    tagview.update();
    writingview.update();
    readingview.update();

    show_all_children();
}

MainWindow::~MainWindow()
{
    //dtor
}
void MainWindow::add_iconset()
{
    Glib::RefPtr<Gtk::IconFactory> icons = Gtk::IconFactory::create();
    icons->add(Gtk::StockID("NOTAG"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/notag-icon.png")));
    icons->add(Gtk::StockID("NOTREADING"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/notreading-icon.png")));
    icons->add(Gtk::StockID("NOPUBLISHER"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/nopublisher-icon.png")));
    icons->add(Gtk::StockID("NOATTACHMENT"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/noattach-icon.png")));
    icons->add(Gtk::StockID("PRL-BOOK"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/book-icon.png")));
    icons->add(Gtk::StockID("PRL-ARTICLE"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/article-icon.png")));
    icons->add(Gtk::StockID("PRL-ALLITEMS"), Gtk::IconSet(Gdk::Pixbuf::create_from_file(utils::get_data_dir()+"images/allitems-icon.png")));
    icons->add_default();
}
void MainWindow::on_action_file_synczotero()
{
	std::string fn=Glib::get_tmp_dir()+"/prl_tmp.backup";
	std::string zotero_fn=Glib::get_home_dir()+"/.mozilla/zotero/zotero.sqlite";
	doc.data_export(fn);
	Gio::init();
	Glib::RefPtr<Gio::File> zfile = Gio::File::create_for_path(zotero_fn);
	Glib::RefPtr<Gio::File> db = Gio::File::create_for_path(dbfile);
	zfile->copy(db,Gio::FILE_COPY_OVERWRITE );
	doc.set_dbfile(dbfile);
	doc.data_import(fn);
	publisherview.update();
    tagview.update();
    writingview.update();
    readingview.update();
}
void MainWindow::on_action_file_import()
{
    Gtk::FileChooserDialog dialog("Please choose a backup file",Gtk::FILE_CHOOSER_ACTION_OPEN);
    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
    dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
    int result = dialog.run();
    if (result==Gtk::RESPONSE_OK)
    {
        doc.data_import(dialog.get_filename());
    }
}
void MainWindow::on_action_file_export()
{
    Gtk::FileChooserDialog dialog("Please choose a backup file",Gtk::FILE_CHOOSER_ACTION_OPEN);
    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
    dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
    int result = dialog.run();
    if (result==Gtk::RESPONSE_OK)
    {
        doc.data_export(dialog.get_filename());
    }
}
void MainWindow::on_action_file_quit()
{
    hide();
}
void MainWindow::on_action_view_allitems()
{
    docview.update();
    publisherview.update();
    filterview.clear();
}
void MainWindow::on_action_view_article()
{
    docview.viewarticle ();
    publisherview.viewarticleitem();
    filterview.clear();
}
void MainWindow::on_action_view_book()
{
    docview.viewbook ();
    publisherview.viewbookitem();
    filterview.clear();
}
void MainWindow::on_action_view_fullscreen()
{
    if (m_fullscreenAction->get_active()) fullscreen();
    else
        unfullscreen();
}
void MainWindow::on_action_view_noattachment()
{
    docview.viewnopdfdocument ();
    publisherview.viewarticleitem();
    filterview.clear();
}
void MainWindow::on_action_filter_nopublisher()
{
    sdms::NoPublisherFilter nc;
    nc.set_documents(&doc);
    nc.eval();
    filterview.add(nc);
}
void MainWindow::on_action_filter_notag()
{
    sdms::NoTagFilter nc;
    nc.set_documents(&doc);
    nc.eval();
    filterview.add(nc);
}
void MainWindow::on_action_filter_notreading()
{
    sdms::NotReading nc;
    nc.set_documents(&doc);
    nc.eval();
    filterview.add(nc);
}
void MainWindow::on_action_help_about()
{
    Gtk::AboutDialog dialog;
    dialog.set_name("Personal Reading library");
    dialog.set_version("0.1.0");
    dialog.set_copyright("Liangxu Wang");
    dialog.set_comments(" a frontend of zotero");
    dialog.set_comments("Organize your documents in gtk way");
    dialog.set_license("LGPL");

    dialog.set_website("http://wlx.westgis.ac.cn");
    dialog.set_website_label("Authohr blog");

    std::list<Glib::ustring> list_authors;
    list_authors.push_back("Liangxu Wang");
    //list_authors.push_back("Somebody Else");
    dialog.set_authors(list_authors);
    dialog.run();
}
void MainWindow::install_menu_hints(const Glib::RefPtr<Gtk::Action>& action, Gtk::Widget* widget)
{
    if(dynamic_cast<Gtk::MenuItem*>(widget))
    {
        (static_cast<Gtk::MenuItem*>(widget))->signal_select().connect(sigc::bind(sigc::mem_fun(*this, &MainWindow::on_show_menu_tip), action));
        (static_cast<Gtk::MenuItem*>(widget))->signal_deselect().connect(sigc::mem_fun(*this, &MainWindow::on_clear_menu_tip));
    }
}

void MainWindow::on_show_menu_tip(const Glib::RefPtr<Gtk::Action>& action)
{
    Glib::ustring tip = action->property_tooltip();
    if (tip == "") tip = " ";
    statusbar.push(" " + tip);
}

void MainWindow::on_clear_menu_tip()
{
    statusbar.pop();
}

